#include "KSocketAction.h"
#include "KDebug.h"
#include "KNetScene.h"

KSocketAction::KSocketAction() : m_item(NULL), m_sock(NULL), m_errors(0)
{
}

void KSocketAction::abortOnce()
{
    if (errors() == 1) {
        abortImp();
    }
}

void KSocketAction::abortOnce(int reason)
{
    if (errors() == 1) {
        abortImp(reason);
    }
}

LONG KSocketAction::errors(bool increase)
{
    if (increase) {
        return InterlockedIncrement(&m_errors);
    } else {
        return m_errors;
    }
}

KNetScene *KSocketAction::scene() const
{
    if (m_item) {
        return m_item->scene();
    } else {
        return NULL;
    }
}

bool KSocketAction::postMessage(KKey *key)
{
    assert(m_item != NULL);
    return m_item->postMessage(m_sock, key);
}

bool KSocketAction::receive(size_t length, KKey *key)
{
    assert(m_item != NULL);
    return m_item->receive(m_sock, length, key);
}

bool KSocketAction::send(KStorage *storage, size_t length)
{
    assert(m_item != NULL);
    return m_item->send(m_sock, storage, length);
}

bool KSocketAction::send(const void *data, size_t length, KKey *key)
{
    assert(m_item != NULL);
    return m_item->send(m_sock, data, length, key);
}

bool KSocketAction::transmit(HANDLE hFile, size_t length, KKey *key, size_t blockLen, KPackage *head, KPackage *tail)
{
    assert(m_item != NULL);
    return m_item->transmit(m_sock, hFile, length, key, blockLen, head, tail);
}

bool KSocketAction::sendTo(const KIAddress &addrRemote, const void *data, size_t length, KKey *key)
{
    assert(m_item != NULL);
    return m_item->sendTo(m_sock, addrRemote, data, length, key);
}

void KSocketAction::ensureAlive(bool always)
{
    assert(m_item != NULL);
    m_item->ensureAlive(m_sock, always);
}

KDef::Life KSocketAction::lifeBegin()
{
    assert(m_item != NULL);
    return m_item->lifeBegin(m_sock);
}

void KSocketAction::lifeEnd(KDef::Life life)
{
    assert(m_item != NULL);
    m_item->lifeEnd(m_sock, life);
}

void KSocketAction::abortImp()
{
    KDebugMsg("Warning: virtual function KSocketAction::abortImp() called");
}

void KSocketAction::abortImp(int reason)
{
    KDebugMsg("Warning: virtual function KSocketAction::abortImp(int) called");
}

void KSocketAction::setSocket(KSocket *sock)
{
    // Double-checked locking
    if (m_sock != sock) {
        KLocker lock(*this);
        if (m_sock != sock) {
            m_sock = sock;
            onSocketChanged();
        }
    }
}